package upload

import (
	"gorm.io/gorm"
)

// Repository 文件上传数据访问层接口
type Repository interface {
	Create(file *File) error
	GetByID(id uint) (*File, error)
	GetByHash(hash string) (*File, error)
	GetByFileName(fileName string) (*File, error)
	Update(file *File) error
	Delete(id uint) error
	List(req *QueryRequest) ([]*FileInfo, int64, error)
	BatchDelete(ids []uint) error
	GetFilesByUser(userID uint) ([]*File, error)
	CleanupDeletedFiles() error
}

// repository 文件上传数据访问层实现
type repository struct {
	db *gorm.DB
}

// NewRepository 创建文件上传数据访问层
func NewRepository(db *gorm.DB) Repository {
	return &repository{
		db: db,
	}
}

// Create 创建文件记录
func (r *repository) Create(file *File) error {
	return r.db.Create(file).Error
}

// GetByID 根据ID获取文件
func (r *repository) GetByID(id uint) (*File, error) {
	var file File
	err := r.db.First(&file, id).Error
	if err != nil {
		return nil, err
	}
	return &file, nil
}

// GetByHash 根据哈希值获取文件
func (r *repository) GetByHash(hash string) (*File, error) {
	var file File
	err := r.db.Where("hash = ?", hash).First(&file).Error
	if err != nil {
		return nil, err
	}
	return &file, nil
}

// GetByFileName 根据文件名获取文件
func (r *repository) GetByFileName(fileName string) (*File, error) {
	var file File
	err := r.db.Where("file_name = ?", fileName).First(&file).Error
	if err != nil {
		return nil, err
	}
	return &file, nil
}

// Update 更新文件记录
func (r *repository) Update(file *File) error {
	return r.db.Save(file).Error
}

// Delete 删除文件记录
func (r *repository) Delete(id uint) error {
	return r.db.Delete(&File{}, id).Error
}

// List 获取文件列表
func (r *repository) List(req *QueryRequest) ([]*FileInfo, int64, error) {
	var files []*FileInfo
	var total int64

	query := r.db.Model(&File{})

	// 关键词搜索
	if req.Keyword != "" {
		query = query.Where("original_name LIKE ? OR file_name LIKE ?", 
			"%"+req.Keyword+"%", "%"+req.Keyword+"%")
	}

	// 字段筛选
	if req.FileType != "" {
		query = query.Where("file_type = ?", req.FileType)
	}

	if req.Extension != "" {
		query = query.Where("extension = ?", req.Extension)
	}

	if req.StorageType != "" {
		query = query.Where("storage_type = ?", req.StorageType)
	}

	if req.UserID != nil {
		query = query.Where("user_id = ?", *req.UserID)
	}

	if req.Status != nil {
		query = query.Where("status = ?", *req.Status)
	}

	// 获取总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 分页查询
	offset := (req.Page - 1) * req.PageSize
	if err := query.Offset(offset).Limit(req.PageSize).Order("id DESC").Find(&files).Error; err != nil {
		return nil, 0, err
	}

	return files, total, nil
}

// BatchDelete 批量删除文件记录
func (r *repository) BatchDelete(ids []uint) error {
	return r.db.Where("id IN ?", ids).Delete(&File{}).Error
}

// GetFilesByUser 获取用户的所有文件
func (r *repository) GetFilesByUser(userID uint) ([]*File, error) {
	var files []*File
	err := r.db.Where("user_id = ?", userID).Find(&files).Error
	return files, err
}

// CleanupDeletedFiles 清理已删除的文件记录
func (r *repository) CleanupDeletedFiles() error {
	// 永久删除软删除的记录
	return r.db.Unscoped().Where("deleted_at IS NOT NULL").Delete(&File{}).Error
}
